package com.example.feigner;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;

/**
 * feign有负载均衡.
 * Httpclient
 * Okhttp
 * Httpurlconnection
 * RestTemplate
 * 上面是最常见的几种用法，我们今天要介绍的用法比上面的更简单，方便，它就是Feign
 *
 * Feign是一个声明式的REST客户端，它的目的就是让REST调用更加简单。
 *
 * Feign提供了HTTP请求的模板，通过编写简单的接口和插入注解，就可以定义好HTTP请求的参数、格式、地址等信息。
 *
 * 而Feign则会完全代理HTTP请求，我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。
 *
 * SpringCloud对Feign进行了封装，使其支持SpringMVC标准注解和HttpMessageConverters。
 *
 * Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
 */
@SpringBootApplication
@RestController
@EnableDiscoveryClient
@EnableFeignClients(clients = DemoService.class)
@EnableScheduling
@EnableIFeignClients(clients = DemoService.class)
@ServletComponentScan(basePackageClasses=GatewayServlet.class)
public class FeignerApplication {


    @Autowired
    private DemoService demoService;

    @Resource(name="IFeign.DemoService")
    private DemoService iFeignDemoService;

    @Autowired
    private ILoadBalanceClientHttpRequestInterceptor interceptor;

    @Autowired
    @LoadBalanced
    private RestTemplate restTemplate;

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate ();
    }


    @Autowired
    @ILoadBalanced
    private RestTemplate iRestTemplate;

    @Bean
    @ILoadBalanced
    public RestTemplate iRestTemplate(){
        return new RestTemplate ();
    }

    @Bean
    public Object customizer(@ILoadBalanced Collection<RestTemplate> restTemplates) {
        restTemplates.forEach(r -> {
            r.setInterceptors (Arrays.asList (interceptor));
        });
        return new Object();
    }


    @RequestMapping("/")
    public String get(){
        return demoService.getClientNames ();
    }

    @RequestMapping("/2")
    public String get2(){
        return restTemplate.getForObject("http://zkcall/get",String.class)+" 222";
    }

    /**
     * 自实现loadbalance
     * @return
     */
    @RequestMapping("/3")
    public String get3(){
        return iRestTemplate.getForObject("http://zkcall/get",String.class)+" 333";
    }

    @RequestMapping("/4")
    public String get4(){
        return iFeignDemoService.getClientNames ();
    }


    public static void main(String[] args) {
        SpringApplication.run (FeignerApplication.class, args);
    }

}
